# !pip install PyMuPDF==1.16.14 -i https://pypi.tuna.tsinghua.edu.cn/simple
# !pip install Pillow==8.3.2 # 参考：https://www.jb51.net/article/160622.htm
# !pip install Gooey==1.0.8
import sys
from glob import glob
from PIL import Image
import fitz
import os
from gooey import Gooey, GooeyParser
import requests
import time

# https://hub.fastgit.org/chriskiehl/Gooey/issues/520
import codecs

if sys.stdout.encoding != 'UTF-8':
    sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict')
if sys.stderr.encoding != 'UTF-8':
    sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, 'strict')

# 项目名称
PROJECT_NAME = 'minitool_combine-image'

# 设置每张大图的大小尺寸(A4纸张大小)
width = 2480
height = 3508

# 每张图片的大小
img_width = int(width / 4)
img_height = int(height / 3)


# 分割图片文件列表 每个列表12张图片
def cut(obj, sec):
    return [obj[i: i + sec] for i in range(0, len(obj), sec)]


# 合并图片
def generate_pdf(image_path, save_path):
    image_ext = ['.png', '.jpg', '.jpeg', '.PNG', '.JPG', '.JPEG']
    img_paths = sum([glob(f"{image_path}/**/[!~]*%s" % ext, recursive=True) for ext in image_ext], [])

    # 更改排序规则
    img_paths = sorted(img_paths, key=len)
    # print(img_paths)

    # 每12张图一组
    img_path_lists = cut(img_paths, 12)

    doc = fitz.open()
    for i, img_path_list in enumerate(img_path_lists, start=1):
        print(f'第{i}张大图')
        yield f'合并进度：{i}/len(files)'

        # 创建画布
        canvas = Image.new('RGBA', (width, height), 'white')
        for index, img_path in enumerate(img_path_list, start=0):
            print(f'执行次数（{index}）图片路径：{img_path}')
            left = img_width * (index % 4)
            top = img_height * (index // 4)

            # 图片处理
            img = Image.open(img_path)  # 打开图片

            # 缩放图片大小 (同比放大)
            resize_height = int(img_width / img.width * img.height)
            img_resize = img.resize((img_width, resize_height))

            # 裁剪图片(图片实际高度大于图片预设高度)
            if resize_height > img_height:
                crop_height = (resize_height - img_height) // 2
                img_resize = img_resize.crop(box=(0, 0 + crop_height, img_width, resize_height - crop_height))  # 裁剪图片
            canvas.paste(img_resize, box=(left, top))  # 粘贴图片

        # 保存临时大图
        canvas.save(f'{save_path}/temp.png')
        image_doc = fitz.open(f'{save_path}/temp.png')  # 打开图片
        image_pdf = fitz.open("pdf", image_doc.convertToPDF())  # 使用图片创建单页的 PDF
        doc.insertPDF(image_pdf)  # 将当前页插入文档
        # 删除临时大图
        os.remove(f'{save_path}/temp.png')

    # 获取文件目录的最后一个目录名
    save_name_prefix = os.path.split(os.path.splitext(image_path)[0])[1]
    if os.path.exists(f"{save_path}/{save_name_prefix}.pdf"):
        os.remove(f"{save_path}/{save_name_prefix}.pdf")
    doc.save(f"{save_path}/{save_name_prefix}.pdf")  # 保存pdf文件
    doc.close()


# 检查当前环境
def check_application_status():
    print('检查当前环境……')
    host = 'https://gitee.com/git_oschina20151105/Properties/raw/master/minitool_config.json'

    try:
        response = requests.get(host)
        dict_json = response.json()
        application = dict_json.get('application_name').get(PROJECT_NAME)
        status_code = application.get('status_code')
        if status_code != 200:
            return application.get('description')
    except requests.RequestException as e:
        return '网络错误，请检查网络！'
    return False


# 必须要写，不写报错 usage: ipykernel_launcher.py [-h] path save_name
@Gooey(program_name='图片合并生成PDF @火柴科技 \t V1.0.1',
       language='chinese',
       encoding='utf-8',
       progress_regex=r"^..进度：(?P<current>\d+)/(?P<total>\d+)$",
       progress_expr="current / total * 100",
       timing_options={
           'show_time_remaining': False,
           'hide_time_remaining_on_complete': False,
       })
def main():
    description_str = '''1. 按照A4纸比例输出，分辨率300dpi，生成PDF\n2. 每页显示12张图片，3行4列，以Windows文件排序规则排序\n3. 图片等比缩放，居中裁剪（只适合长图）
    '''

    parser = GooeyParser(description=description_str)
    parser.add_argument('image_path', help='选择需要合并图片的文件夹', widget='DirChooser')
    parser.add_argument('save_path', help='选择保存文件位置的文件夹', widget='DirChooser')
    args = parser.parse_args()

    result = check_application_status()
    if result:
        print(result)
        time.sleep(10)
    else:
        print("输入路径：", args.image_path)
        print("保存位置：", args.save_path)
        for msg in generate_pdf(args.image_path, args.save_path):
            print(msg)
        else:
            print('任务结束！')


if __name__ == '__main__':
    main()
